﻿Imports System.ComponentModel

<Serializable()> Public Class BaseNotifyPropertyChangeComponentModel
    Implements INotifyPropertyChanged
    Implements INotifyPropertyChanging

#Region "INotifyPropertyChange"
    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
        Me.VerifyPropertyName(propertyName)
        Dim e As PropertyChangedEventArgs = New PropertyChangedEventArgs(propertyName)
        RaiseEvent PropertyChanged(Me, e)
    End Sub
#End Region
#Region "INotifyPropertyChanging"
    Public Event PropertyChanging(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangingEventArgs) Implements System.ComponentModel.INotifyPropertyChanging.PropertyChanging
    Protected Overridable Sub OnPropertyChanging(ByVal propertyName As String)
        Me.VerifyPropertyName(propertyName)
        Dim e As PropertyChangingEventArgs = New PropertyChangingEventArgs(propertyName)
        RaiseEvent PropertyChanging(Me, e)
    End Sub
#End Region
#Region "Debugging Aides"

    ''' <summary>
    ''' Warns the developer if this object does not have
    ''' a public property with the specified name. This 
    ''' method does not exist in a Release build.
    ''' </summary>
    <Conditional("DEBUG"), DebuggerStepThrough()> _
    Public Sub VerifyPropertyName(ByVal propertyName As String)
        ' Verify that the property name matches a real,  
        ' public, instance property on this object.
        If TypeDescriptor.GetProperties(Me)(propertyName) Is Nothing Then
            Dim msg As String = "Invalid property name: " & propertyName

            If Me.ThrowOnInvalidPropertyName Then
                Throw New Exception(msg)
            Else
                Debug.Fail(msg)
            End If
        End If
    End Sub

    ''' <summary>
    ''' Returns whether an exception is thrown, or if a Debug.Fail() is used
    ''' when an invalid property name is passed to the VerifyPropertyName method.
    ''' The default value is false, but subclasses used by unit tests might 
    ''' override this property's getter to return true.
    ''' </summary>
    <NonSerialized()> Private privateThrowOnInvalidPropertyName As Boolean
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Protected Overridable Property ThrowOnInvalidPropertyName() As Boolean
        Get
            Return privateThrowOnInvalidPropertyName
        End Get
        Set(ByVal value As Boolean)
            privateThrowOnInvalidPropertyName = value
        End Set
    End Property

#End Region

End Class